<!DOCTYPE html>
<html>
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="utf-8">
  
  <title>ryansecreat blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="保持积极昂扬的状态，避免成为别人眼中的傻子">
<meta property="og:type" content="website">
<meta property="og:title" content="ryansecreat blog">
<meta property="og:url" content="http://yoursite.com/page/2/index.html">
<meta property="og:site_name" content="ryansecreat blog">
<meta property="og:description" content="保持积极昂扬的状态，避免成为别人眼中的傻子">
<meta property="og:locale" content="zh-Hans">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="ryansecreat blog">
<meta name="twitter:description" content="保持积极昂扬的状态，避免成为别人眼中的傻子">
  
    <link rel="alternate" href="/atom.xml" title="ryansecreat blog" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  

  
  <link rel="stylesheet" href="/css/style.css">
  

</head>
</html>
<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">ryansecreat blog</a>
      </h1>
      
        <h2 id="subtitle-wrap">
          <a href="/" id="subtitle">smile hard</a>
        </h2>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main">
  
    <article id="post-security" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/04/25/security/" class="article-date">
  <time datetime="2019-04-25T08:49:58.000Z" itemprop="datePublished">2019-04-25</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/04/25/security/">security</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">参考： https://juejin.im/post/5bad9140e51d450e935c6d64#heading-9</span><br><span class="line"></span><br><span class="line">xss 攻击类型分为：反射、存储和dom </span><br><span class="line"></span><br><span class="line">在纯前端渲染中，我们会明确的告诉浏览器：下面要设置的内容是文本（.innerText），还是属性（.setAttribute），还是样式（.style）等等。浏览器不会被轻易的被欺骗，执行预期外的代码了.</span><br><span class="line"></span><br><span class="line">在很多内部、管理系统中，采用纯前端渲染是非常合适的。但对于性能要求高，或有 SEO 需求的页面，我们仍然要面对拼接 HTML 的问题。需要html 转义。</span><br><span class="line"></span><br><span class="line">利用模板引擎</span><br><span class="line">开启模板引擎自带的 HTML 转义功能。例如：</span><br><span class="line">在 ejs 中，尽量使用 &lt;%= data %&gt; 而不是 &lt;%- data %&gt;；</span><br><span class="line">在 doT.js 中，尽量使用 &#123;&#123;! data &#125; 而不是 &#123;&#123;= data &#125;；</span><br><span class="line">在 FreeMarker 中，确保引擎版本高于 2.3.24，并且选择正确的 freemarker.core.OutputFormat。</span><br><span class="line">避免内联事件</span><br><span class="line">尽量不要使用 onLoad=&quot;onload(&apos;&#123;&#123;data&#125;&#125;&apos;)&quot;、onClick=&quot;go(&apos;&#123;&#123;action&#125;&#125;&apos;)&quot; 这种拼接内联事件的写法。在 JavaScript 中通过 .addEventlistener() 事件绑定会更安全。</span><br><span class="line">避免拼接 HTML</span><br><span class="line">前端采用拼接 HTML 的方法比较危险，如果框架允许，使用 createElement、setAttribute 之类的方法实现。或者采用比较成熟的渲染框架，如 Vue/React 等。</span><br><span class="line">时刻保持警惕</span><br><span class="line">在插入位置为 DOM 属性、链接等位置时，要打起精神，严加防范。</span><br><span class="line">增加攻击难度，降低攻击后果</span><br><span class="line">通过 CSP、输入长度配置、接口安全措施等方法，增加攻击的难度，降低攻击的后果。</span><br><span class="line">主动检测和发现</span><br><span class="line">可使用 XSS 攻击字符串和自动扫描工具寻找潜在的 XSS 漏洞。</span><br></pre></td></tr></table></figure>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/04/25/security/" data-id="ck3ya0yit00140d8sj99vdk66" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/安全/">安全</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-typescript" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/02/25/typescript/" class="article-date">
  <time datetime="2019-02-25T02:16:27.000Z" itemprop="datePublished">2019-02-25</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/02/25/typescript/">typescript</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="只读属性"><a href="#只读属性" class="headerlink" title="只读属性"></a>只读属性</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">interface Point &#123;</span><br><span class="line">    readonly x: number;</span><br><span class="line">    readonly y: number;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="接口继承"><a href="#接口继承" class="headerlink" title="接口继承"></a>接口继承</h3><pre><code>支持多重继承, 比较有意思的事接口可以继承类
</code></pre><h3 id="枚举类型"><a href="#枚举类型" class="headerlink" title="枚举类型"></a>枚举类型</h3> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">enum Color &#123;Red, Green, Blue&#125;</span><br><span class="line">let c: Color = Color.Green;</span><br></pre></td></tr></table></figure>
<h3 id="any"><a href="#any" class="headerlink" title="any"></a>any</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">let notSure: any = 4;</span><br><span class="line">notSure = &quot;maybe a string instead&quot;;</span><br><span class="line">notSure = false; // okay, definitely a boolean</span><br></pre></td></tr></table></figure>
<h3 id="类型断言"><a href="#类型断言" class="headerlink" title="类型断言"></a>类型断言</h3><p>as 和 &lt;&gt;</p>
<h3 id="剩余参数"><a href="#剩余参数" class="headerlink" title="剩余参数"></a>剩余参数</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">function invokeLater(args: any[], callback: (...args: any[]) =&gt; void) &#123;</span><br><span class="line">    /* ... Invoke callback with &apos;args&apos; ... */</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// Unsound - invokeLater &quot;might&quot; provide any number of arguments</span><br><span class="line">invokeLater([1, 2], (x, y) =&gt; console.log(x + &apos;, &apos; + y));</span><br></pre></td></tr></table></figure>
<h3 id="交叉类型-特色"><a href="#交叉类型-特色" class="headerlink" title="交叉类型 特色"></a>交叉类型 特色</h3><p>Person &amp; Serializable &amp; Loggable同时是 Person 和 Serializable 和 Loggable。 就是说这个类型的对象同时拥有了这三种类型的成员。</p>
<h3 id="联合类型"><a href="#联合类型" class="headerlink" title="联合类型"></a>联合类型</h3><p> 如果一个值的类型是 A | B，我们能够 确定的是它包含了 A 和 B中共有的成员。 – 用来做代码检查的<br> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">interface Bird &#123;</span><br><span class="line">    fly();</span><br><span class="line">    layEggs();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">interface Fish &#123;</span><br><span class="line">    swim();</span><br><span class="line">    layEggs();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">function getSmallPet(): Fish | Bird &#123;</span><br><span class="line">    // ...</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">let pet = getSmallPet();</span><br><span class="line">pet.layEggs(); // okay</span><br><span class="line">pet.swim();    // error</span><br><span class="line"></span><br><span class="line">需要类型转换：(&lt;Fish&gt;pet).swim()</span><br></pre></td></tr></table></figure></p>
<h3 id="谓词为-parameterName-is-Type这种形式"><a href="#谓词为-parameterName-is-Type这种形式" class="headerlink" title="谓词为 parameterName is Type这种形式"></a>谓词为 parameterName is Type这种形式</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">function isFish(pet: Fish | Bird): pet is Fish &#123;</span><br><span class="line">    return (&lt;Fish&gt;pet).swim !== undefined;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="参数指定默认值"><a href="#参数指定默认值" class="headerlink" title="参数指定默认值"></a>参数指定默认值</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">function keepWholeObject(wholeObject: &#123; a: string, b?: number &#125;) &#123;</span><br><span class="line">    let &#123; a, b = 1001 &#125; = wholeObject;</span><br><span class="line">&#125;</span><br><span class="line">TypeScript编译器不允许展开泛型函数上的类型参数 。 这个特性会在TypeScript的未来版本中考虑实现。 ...</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">function buildName(firstName: string, lastName: string = &apos;Cat&apos;) &#123;</span><br><span class="line">    return firstName + &apos; &apos; + lastName;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="数组泛型"><a href="#数组泛型" class="headerlink" title="数组泛型"></a>数组泛型</h3><p>Array<number>  </number></p>
<p>let list: any[] = [‘Xcat Liu’, 25, { website: ‘<a href="http://xcatliu.com&#39;" target="_blank" rel="noopener">http://xcatliu.com&#39;</a> }];</p>
<p>用接口表示数组：</p>
<p>interface NumberArray {<br>    [index: number]: number;<br>}</p>
<h3 id="声明语句"><a href="#声明语句" class="headerlink" title="声明语句"></a>声明语句</h3><p>declare var jQuery: (string) =&gt; any;</p>
<p>我们约定声明文件以 .d.ts 为后缀。</p>
<h3 id="元组"><a href="#元组" class="headerlink" title="元组"></a>元组</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">let xcatliu: [string, number];</span><br><span class="line">xcatliu[0] = &apos;Xcat Liu&apos;;</span><br><span class="line">xcatliu[1] = 25;</span><br></pre></td></tr></table></figure>
<h3 id="命名空间-来源于C"><a href="#命名空间-来源于C" class="headerlink" title="命名空间  来源于C"></a>命名空间  来源于C</h3><p>namespace Validation {}</p>
<p>import 别名<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">amespace Shapes &#123;</span><br><span class="line">    export namespace Polygons &#123;</span><br><span class="line">        export class Triangle &#123; &#125;</span><br><span class="line">        export class Square &#123; &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">import polygons = Shapes.Polygons;</span><br><span class="line">let sq = new polygons.Square();</span><br></pre></td></tr></table></figure></p>
<h3 id="index"><a href="#index" class="headerlink" title="index"></a>index</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">type Index = &apos;a&apos; | &apos;b&apos; | &apos;c&apos;</span><br><span class="line">type FromIndex = &#123; [k in Index]?: number &#125;</span><br><span class="line"></span><br><span class="line">const good: FromIndex = &#123;b:1, c:2&#125;</span><br><span class="line"></span><br><span class="line">// Error:</span><br><span class="line">// Type &apos;&#123; b: number; c: number; d: number; &#125;&apos; is not assignable to type &apos;FromIndex&apos;.</span><br><span class="line">// Object literal may only specify known properties, and &apos;d&apos; does not exist in type &apos;FromIndex&apos;.</span><br><span class="line">const bad: FromIndex = &#123;b:1, c:2, d:3&#125;;</span><br></pre></td></tr></table></figure>
<h3 id="this-参数"><a href="#this-参数" class="headerlink" title="this 参数"></a>this 参数</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">interface Card &#123;</span><br><span class="line">    suit: string;</span><br><span class="line">    card: number;</span><br><span class="line">&#125;</span><br><span class="line">interface Deck &#123;</span><br><span class="line">    suits: string[];</span><br><span class="line">    cards: number[];</span><br><span class="line">    createCardPicker(this: Deck): () =&gt; Card;</span><br><span class="line">&#125;</span><br><span class="line">let deck: Deck = &#123;</span><br><span class="line">    suits: [&quot;hearts&quot;, &quot;spades&quot;, &quot;clubs&quot;, &quot;diamonds&quot;],</span><br><span class="line">    cards: Array(52),</span><br><span class="line">    // NOTE: The function now explicitly specifies that its callee must be of type Deck</span><br><span class="line">    createCardPicker: function(this: Deck) &#123;</span><br><span class="line">        return () =&gt; &#123;</span><br><span class="line">            let pickedCard = Math.floor(Math.random() * 52);</span><br><span class="line">            let pickedSuit = Math.floor(pickedCard / 13);</span><br><span class="line"></span><br><span class="line">            return &#123;suit: this.suits[pickedSuit], card: pickedCard % 13&#125;;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/02/25/typescript/" data-id="ck3ya0yiq00120d8s4pjpvcgf" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/ts/">ts</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-gitInfo" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/02/20/gitInfo/" class="article-date">
  <time datetime="2019-02-20T09:58:18.000Z" itemprop="datePublished">2019-02-20</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/02/20/gitInfo/">gitInfo</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li>git rm –cached  从git索引和缓存中删除 </li>
<li>git mv 重命名或者移动文件</li>
<li>git reset –soft “HEAD^” 留下当前变更内容</li>
<li>git reset head 从当前缓存区删除</li>
<li>git checkout .  撤销当前工作区修改</li>
<li>git commit –amend 修改上次提交信息</li>
<li>git log –oneline/–raw </li>
<li>checkout只会移动HEAD指针，reset会改变HEAD的引用值。</li>
<li>git config –global user.name [user.email]</li>
<li>git tag -a ‘annotate’ -m ‘message’</li>
<li>git remote set-url –add <name> <newurl>  添加多个url</newurl></name></li>
<li>git tag -d <tag-name>  </tag-name></li>
<li>git status –ignored  显示忽略掉文件</li>
<li>git checkout –orphan <branch-name>  新建没有commit的分支</branch-name></li>
<li>git push origin :refs/tags/<tag-name>  删除远程tag</tag-name></li>
<li>git branch -u &lt;origin/mybranch&gt; 设置远程分支 </li>
<li>git branch -vv 查看本地分之关联情况</li>
<li>git checkout -  最近两个分子间切换</li>
<li>git commit -m “Big-ass commit” –allow-empty</li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/02/20/gitInfo/" data-id="ck3ya0yi7000j0d8snfenygvv" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/git/">git</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-package" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/02/14/package/" class="article-date">
  <time datetime="2019-02-14T09:19:12.000Z" itemprop="datePublished">2019-02-14</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2019/02/14/package/">package</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <ol>
<li>Opn: A better node-open. Opens stuff like websites, files, executables. Cross-platform.</li>
<li>Ora:进度条和文字。</li>
<li>joi：数据验</li>
<li>satisfies ：版本工具</li>
<li>minimist：简单的参数处理</li>
<li>read-pkg:规范化解析pkg</li>
<li>inquirer:询问时可以给出选项</li>
<li>Resovel:解析包的安装路径</li>
<li>slash:Convert Windows backslash paths to slash paths: foo\bar ➔ foo/bar</li>
<li>klaw-sync:回遍历出所有文件，并返回文件路径和文件夹</li>
<li>mime-types content-type 工具：1. 可以根据文件后缀获取 2. 根据content-type获取charset 3. 根据content-type 获取默认的文件名</li>
<li>CodeMirror是一个运行在浏览器中的在线代码编辑器，支持100多种语言，高度可定制。</li>
<li>@typescript-eslint/eslint-plugin.  eslint 检测typescript </li>
<li>nanoid  A tiny, secure, URL-friendly, unique string ID generator for JavaScript.</li>
<li>mm 对mudule 中的方法mock</li>
<li><p>numerify  用来格式化数字 </p>
</li>
<li><p>utils-lite  前端提供debounce、thorttling、clone、cloneDeep 等方法</p>
</li>
<li>is-type-of   node check 数据类型</li>
<li>on-finished  Execute a callback when a HTTP request closes, finishes, or errors</li>
<li><p>await-event  封装了promise </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> PassThrough = <span class="built_in">require</span>(<span class="string">'stream'</span>).PassThrough</span><br><span class="line"> </span><br><span class="line"><span class="keyword">var</span> stream = <span class="keyword">new</span> PassThrough()</span><br><span class="line"><span class="comment">// you attach it directly on an event emitter</span></span><br><span class="line">stream.await = <span class="built_in">require</span>(<span class="string">'await-event'</span>)</span><br><span class="line"> </span><br><span class="line">co(<span class="function"><span class="keyword">function</span>* (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> chunk = <span class="keyword">yield</span> stream.await(<span class="string">'data'</span>)</span><br><span class="line">  <span class="keyword">var</span> chunk = <span class="keyword">yield</span> stream.await(<span class="string">'data'</span>)</span><br><span class="line">  <span class="keyword">var</span> chunk = <span class="keyword">yield</span> stream.await(<span class="string">'data'</span>)</span><br><span class="line">&#125;).catch(noop)</span><br><span class="line"> </span><br><span class="line">stream.write(<span class="string">'some chunk’)</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>get-ready  NodeJS mixin to add one-time ready event</p>
</li>
<li>ShellJS 是Unix shell命令在Node.js API上的可移植实现</li>
<li>graceful-process   graceful exit process even parent exit on SIGKILL.</li>
<li>semver.gte(process.version, ‘7.0.0’)  版本的比对 </li>
<li>pkgfiles  自动再package中添加 npm publish 文件</li>
<li>depd  标注方法deprecating </li>
<li>http-errors   http错误  </li>
<li>Global-tunnel  http请求的全局代理  </li>
<li><p>humanize-ms  转义为ms  </p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">transform humanize time to ms  ms(&apos;1s&apos;) // 1000</span><br><span class="line">ms(1000) // 1000</span><br></pre></td></tr></table></figure>
</li>
<li><p>Exceljs 一个功能强大的excel 处理包</p>
</li>
<li>ready-callback 所有注册的事件完成后，才执行ready中方法</li>
<li>Get-ready  NodeJS mixin to add one-time ready event，ready 后执行相关方法</li>
<li>xml2js  将xml 转换为json </li>
<li>debug  调试状态输出  debug=<em>  debug=work:</em>   </li>
<li>delegates  node模块中代理proto中属性的方法、setter和getter</li>
<li>chokidar filewatch </li>
<li>Puppeteer  headless browser</li>
<li>cross-env Run scripts that set and use environment variables across platforms</li>
<li>simplemde  markdown editor </li>
<li><p>serialize-javascript  Serialize JavaScript to a superset of JSON that includes regular expressions and functions.<br>1.route-cache  express router cache</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> routeCache = <span class="built_in">require</span>(<span class="string">'route-cache'</span>);</span><br><span class="line"> </span><br><span class="line"><span class="comment">// cache route for 20 seconds</span></span><br><span class="line">app.get(<span class="string">'/index'</span>, routeCache.cacheSeconds(<span class="number">20</span>), <span class="function"><span class="keyword">function</span>(<span class="params">req, res</span>)</span>&#123;</span><br><span class="line">  <span class="comment">// do your dirty work here...</span></span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'you will only see this every 20 seconds.'</span>);</span><br><span class="line">  res.send(<span class="string">'this response will be cached'</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
</li>
<li><p>Ws server 端的websoket </p>
</li>
<li>fastclick  解决浏览器点击的延迟</li>
<li>Qs  A querystring parsing and stringifying library with some added security.</li>
<li>lru-cache  A cache object that deletes the least-recently-used items.</li>
<li>memory-fs  A simple in-memory filesystem. Holds data in a javascript object</li>
<li>faker.js  generate massive amounts of fake data in the browser and node.js</li>
<li>parseurl 等同node url parse，加了cache</li>
<li>vue-lazy-component   Vue.js 2.x 组件级懒加载方案-Vue.js 2.x component level lazy loading solution</li>
<li>async-validator  数据验证</li>
<li>fast-safe-stringify    Safe and fast serialization alternative to JSON.stringify.</li>
<li>node-notifier   Send cross platform native notifications using Node.js.</li>
<li>dateformat   node 时间处理函数</li>
<li>agentkeepalive  defaut is keepalive</li>
<li>copy-to   copy an object’s properties to another one, include propertiy, getter and setter.</li>
<li><p>platform   A platform detection library that works on nearly all JavaScript platforms.</p>
</li>
<li><p>svg-captcha 验证码  </p>
</li>
<li>vue-virtual-scroller  加载大量数据</li>
</ol>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/02/14/package/" data-id="ck3ya0yib000n0d8sbtp3hwbc" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/useful-package/">useful package</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-postgre" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2017/02/21/postgre/" class="article-date">
  <time datetime="2017-02-21T03:18:37.000Z" itemprop="datePublished">2017-02-21</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2017/02/21/postgre/">postgre</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">db.many(query, values); // expects one or more rows</span><br><span class="line">db.one(query, values); // expects a single row</span><br><span class="line">db.none(query, values); // expects no rows</span><br><span class="line">db.any(query, values); // expects anything, same as `manyOrNone`</span><br><span class="line">db.oneOrNone(query, values); // expects 1 or 0 rows</span><br><span class="line">db.manyOrNone(query, values); // expects anything, same as `any`</span><br></pre></td></tr></table></figure>
<p>The library supports named parameters in query formatting, with the syntax of $<em>propName</em>, where * is any of the following open-close pairs: {}, (), &lt;&gt;, [], //</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">db.query(&apos;SELECT * FROM users WHERE name=$&#123;name&#125; AND active=$/active/&apos;, &#123;</span><br><span class="line">    name: &apos;John&apos;,</span><br><span class="line">    active: true</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<p>this 的用法：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">var doc = &#123;</span><br><span class="line">    id: 123,</span><br><span class="line">    body: &quot;some text&quot;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">db.none(&quot;INSERT INTO documents(id, doc) VALUES($&#123;id&#125;, $&#123;this&#125;)&quot;, doc)</span><br><span class="line">    .then(function () &#123;</span><br><span class="line">        // success;</span><br><span class="line">    &#125;)</span><br><span class="line">    .catch(function (error) &#123;</span><br><span class="line">        // error;</span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure></p>
<p>which will execute:</p>
<p>INSERT INTO documents(id, doc) VALUES(123, ‘{“id”:123,”body”:”some text”}’)</p>
<p>执行函数</p>
<p>And when you are not expecting any return results, call db.proc instead. Both methods return a Promise object, but db.proc doesn’t take a qrm parameter, always assuming it is one|none.<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">db.func(&apos;findAudit&apos;, [123, new Date()])</span><br><span class="line">    .then(function (data) &#123;</span><br><span class="line">        console.log(data); // printing the data returned </span><br><span class="line">    &#125;)</span><br><span class="line">    .catch(function (error) &#123;</span><br><span class="line">        console.log(error); // printing the error </span><br><span class="line">    &#125;);</span><br><span class="line">db.proc();</span><br></pre></td></tr></table></figure></p>
<p>公用一个连接：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">db.task(function (t) &#123;</span><br><span class="line">    // `t` and `this` here are the same;</span><br><span class="line">    // execute a chain of queries;</span><br><span class="line">&#125;)</span><br><span class="line">    .then(function (data) &#123;</span><br><span class="line">        // success;</span><br><span class="line">    &#125;)</span><br><span class="line">    .catch(function (error) &#123;</span><br><span class="line">        // failed;    </span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure>
<p>事物：其中可以嵌套事物</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">db.tx(function (t) &#123;</span><br><span class="line">    // t = this;</span><br><span class="line">    return t.batch([</span><br><span class="line">        t.one(&quot;insert into users(name) values($1) returning id&quot;, &quot;John&quot;),</span><br><span class="line">        t.one(&quot;insert into events(code) values($1) returning id&quot;, 123)</span><br><span class="line">    ]);</span><br><span class="line">&#125;)</span><br><span class="line">    .spread(function (user, event) &#123;</span><br><span class="line">        // print new user id + new event id;</span><br><span class="line">        console.log(&quot;DATA:&quot;, user.id, event.id);</span><br><span class="line">    &#125;)</span><br><span class="line">    .catch(function (error) &#123;</span><br><span class="line">        console.log(&quot;ERROR:&quot;, error); // print the error;</span><br><span class="line">    &#125;)</span><br><span class="line">    .finally(function () &#123;</span><br><span class="line">    </span><br><span class="line"></span><br><span class="line">        pgp.end(); // for immediate app exit, closing the connection pool.   关闭连接池，是的一般不需要</span><br><span class="line">        </span><br><span class="line">        If, however you normally exit your application by killing the NodeJS process, then you don&apos;t need to use it.</span><br><span class="line"></span><br><span class="line">        </span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure>
<p>设置隔离级别：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">var TransactionMode = pgp.txMode.TransactionMode;</span><br><span class="line">var isolationLevel = pgp.txMode.isolationLevel;</span><br><span class="line"></span><br><span class="line">// Create a reusable transaction mode (serializable + read-only + deferrable):</span><br><span class="line">var tmSRD = new TransactionMode(&#123;</span><br><span class="line">    tiLevel: isolationLevel.serializable,</span><br><span class="line">    readOnly: true,</span><br><span class="line">    deferrable: true</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">function myTransaction() &#123;</span><br><span class="line">    return this.query(&apos;SELECT * FROM table&apos;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">myTransaction.txMode = tmSRD; // assign transaction mode;</span><br><span class="line"></span><br><span class="line">db.tx(myTransaction)</span><br><span class="line">    .then(function()&#123;</span><br><span class="line">        // success;</span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure>
<p>重置promise：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">var promise = require(&apos;bluebird&apos;);</span><br><span class="line">var options = &#123;</span><br><span class="line">    promiseLib: promise</span><br><span class="line">&#125;;</span><br><span class="line">var pgp = require(&apos;pg-promise&apos;)(options);</span><br></pre></td></tr></table></figure>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2017/02/21/postgre/" data-id="ck3ya0yin000y0d8sxru4j3lf" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/postgre/">postgre</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-interview" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2017/01/23/interview/" class="article-date">
  <time datetime="2017-01-23T10:25:52.000Z" itemprop="datePublished">2017-01-23</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2017/01/23/interview/">interview</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <p> 而在底层，Node.js借助libuv来作为抽象封装层， 从而屏蔽不同操作系统的差异，Node可以借助livuv来来实现多线程。</p>
<p> <img src="http://www.admin10000.com/UploadFiles/Document/201509/30/20150930072020634231.PNG" alt="image"></p>
<p> 事件循环是单线程的，从下图可以看出</p>
<p> <img src="http://www.admin10000.com/UploadFiles/Document/201509/30/20150930072028113909.PNG" alt="image"></p>
<p> 所有的同步任务在主线程上执行，形成一个任务栈。所有的异步任务的回调在另一队列中，只有执行完</p>
<p> tTimeout()只是将事件插入了”任务队列”，必须等到当前代码（执行栈）执行完，主线程才会去执行它指定的回调函数。要是当前代码耗时很长，有可能要等很久，所以并没有办法保证，回调函数一定会在setTimeout()指定的时间执行。</p>
<p> Node.js也是单线程的Event Loop，但是它的运行机制不同于浏览器环境。</p>
<p> <img src="http://image.beekka.com/blog/2014/bg2014100803.png" alt="image"></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">process.nextTick(function A() &#123;</span><br><span class="line">  console.log(1);</span><br><span class="line">  process.nextTick(function B()&#123;console.log(2);&#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">setTimeout(function timeout() &#123;</span><br><span class="line">  console.log(&apos;TIMEOUT FIRED&apos;);</span><br><span class="line">&#125;, 0)</span><br><span class="line">// 1</span><br><span class="line">// 2</span><br><span class="line">// TIMEOUT FIRED</span><br></pre></td></tr></table></figure>
<p>上面代码中，由于process.nextTick方法指定的回调函数，总是在当前”执行栈”的尾部触发，所以不仅函数A比setTimeout指定的回调函数timeout先执行，而且函数B也比timeout先执行。这说明，如果有多个process.nextTick语句（不管它们是否嵌套），将全部在当前”执行栈”执行。   setImmediate总是将事件注册到下一轮Event Loop</p>
<p>　测试金字塔指的是： 当我们在编写测试用例时，底层的单元测试应该远比上层的端到端测试要多。
　</p>
<p>数组的shift和unshift  push 和 pop </p>
<p>node 优势：非阻塞IO、高并发、丰富的生态环境</p>
<p> node有哪些全局对象?<br>参考答案: process, console, Buffer和exports<br><img src="https://camo.githubusercontent.com/233315761d49d4c75fe7969e36bda22ecf5bbc0f/687474703a2f2f6a6f616f7073696c76612e6769746875622e696f2f74616c6b732f456e642d746f2d456e642d4a6176615363726970742d776974682d7468652d4d45414e2d537461636b2f696d672f6e6f64656a732d617263682d7070742e706e67" alt="image"></p>
<p>process有哪些常用方法?<br>参考答案: process.stdin, process.stdout, process.stderr, process.on, process.env, process.argv, process.arch, process.platform, process.exit</p>
<p>通过domain获取eventemmiter 的异常：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">var domain = require(&apos;domain&apos;);</span><br><span class="line">    var myDomain = domain.create();</span><br><span class="line">    myDomain.on(&apos;error&apos;, function(err)&#123;</span><br><span class="line">        console.log(&apos;domain接收到的错误事件:&apos;, err);</span><br><span class="line">    &#125;); // 接收事件并打印</span><br><span class="line">    myDomain.run(function()&#123;</span><br><span class="line">        var emitter1 = new MyEmitter();</span><br><span class="line">        emitter1.emit(&apos;error&apos;, &apos;错误事件来自emitter1&apos;);</span><br><span class="line">        emitter2 = new MyEmitter();</span><br><span class="line">        emitter2.emit(&apos;error&apos;, &apos;错误事件来自emitter2&apos;);</span><br><span class="line">    &#125;);</span><br></pre></td></tr></table></figure>
<p>supper 代表父类构造函数和原形</p>
<p>原生构造函数：<br>Boolean()<br>Number()<br>String()<br>Array()<br>Date()<br>Function()<br>RegExp()<br>Error()<br>Object()</p>
<p>Es6 可以继承这些原生的构造函数</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">class MyArray extends Array &#123;</span><br><span class="line">  constructor(...args) &#123;</span><br><span class="line">    super(...args);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">var arr = new MyArray();</span><br><span class="line">arr[0] = 12;</span><br><span class="line">arr.length // 1</span><br><span class="line"></span><br><span class="line">arr.length = 0;</span><br><span class="line">arr[0] // undefined</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">class ExtendableError extends Error &#123;</span><br><span class="line">  constructor(message) &#123;</span><br><span class="line">    super();</span><br><span class="line">    this.message = message;</span><br><span class="line">    this.stack = (new Error()).stack;</span><br><span class="line">    this.name = this.constructor.name;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">class MyError extends ExtendableError &#123;</span><br><span class="line">  constructor(m) &#123;</span><br><span class="line">    super(m);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">var myerror = new MyError(&apos;ll&apos;);</span><br><span class="line">myerror.message // &quot;ll&quot;</span><br><span class="line">myerror instanceof Error // true</span><br><span class="line">myerror.name // &quot;MyError&quot;</span><br><span class="line">myerror.stack</span><br></pre></td></tr></table></figure>
<p>定义get set ,可在方法体内部拦截</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">class MyClass &#123;</span><br><span class="line">  constructor() &#123;</span><br><span class="line">    // ...</span><br><span class="line">  &#125;</span><br><span class="line">  get prop() &#123;</span><br><span class="line">    return &apos;getter&apos;;</span><br><span class="line">  &#125;</span><br><span class="line">  set prop(value) &#123;</span><br><span class="line">    console.log(&apos;setter: &apos;+value);</span><br><span class="line">  &#125;</span><br><span class="line">  * [Symbol.iterator]() &#123;</span><br><span class="line">    for (let arg of this.args) &#123;</span><br><span class="line">      yield arg;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>Stream有什么好处?<br>参考答案: 非阻塞式数据处理提升效率，片断处理节省内存，管道处理方便可扩展等.</p>
<p>fs.watch和fs.watchFile有什么区别，怎么应用?<br>参考答案: 二者主要用来监听文件变动．fs.watch利用操作系统原生机制来监听，可能不适用网络文件系统; fs.watchFile则是定期检查文件状态变更，适用于网络文件系统，但是相比fs.watch有些慢，因为不是实时机制．</p>
<p>实现一个简单的HTTP 服务器。<br>require(‘http’).createServer(function(req,res){}).listen(300);</p>
<p>spawn应用来运行返回大量数据的子进程，如图像处理，文件读取等。而exec则应用来运行只返回少量返回值的子进程，如只返回一个状态码。</p>
<p>有哪些常用方法可以防止程序崩溃?</p>
<p>参考答案: 1) try-catch-finally 2) EventEmitter/Stream error事件处理 3) domain统一控制 4) jshint静态检查 5) jasmine/mocha进行单元测试</p>
<p>要监控nodejs的内存使用的话，需要安装memwathch 模块</p>
<p>nodejs C++ 扩展的实现：<br><a href="https://my.oschina.net/yushulx/blog/423704" target="_blank" rel="noopener">https://my.oschina.net/yushulx/blog/423704</a></p>
<p>process.argv 数组的第一个元素永远都会是 node，并且第二个参数总是指向你的程序的路径，所以，你应该从第三个元素</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">regex test   if (/^\/api\/parsetime/.test(req.url))</span><br></pre></td></tr></table></figure>
<p>回调函数的规则：err 为第一个参数</p>
<p>文件的总行：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">var lines = contents.toString().split(&apos;\n&apos;).length - 1</span><br></pre></td></tr></table></figure></p>
<p>fs.unlink 删除文件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">//创建一个tcp 服务器</span><br><span class="line">var net = require(&apos;net&apos;)</span><br><span class="line"></span><br><span class="line">var server = net.createServer(function (socket) &#123;</span><br><span class="line"></span><br><span class="line">  // socket 处理逻辑</span><br><span class="line"></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line">server.listen(8000)</span><br></pre></td></tr></table></figure>
<p>使用 socket.write(data) 可以写数据到 socket 中，用 socket.end() 可以关闭一个 socket。另外， .end() 方法也可以接收一个数据对象作为参数，因此，你可简单地使用 socket.end(data) 来完成写数据和关闭两个操作。</p>
<p>concat-stream：会连接多个stream,参数中不指定encoding 的话，会自行推断。</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">var arrays = concat(&#123; encoding: &apos;array&apos; &#125;, function(out) &#123;</span><br><span class="line">    t.deepEqual(out, [1,2,3,4,5,6])</span><br><span class="line">  &#125;)</span><br><span class="line">  arrays.write([1,2,3])</span><br><span class="line">  arrays.write([4,5,6])</span><br><span class="line">  arrays.end()</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fs.createReadStream(file).pipe(process.stdout);</span><br></pre></td></tr></table></figure>
<p>使用through2 对流数据进行转换：</p>
<p>通过split 将流中的数据分行：</p>
<p>You can use the <code>split</code> module to split input by newlines. For example:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">var split = require(&apos;split&apos;);</span><br><span class="line">process.stdin</span><br><span class="line">    .pipe(split())</span><br><span class="line">    .pipe(through2(function (line, _, next) &#123;</span><br><span class="line">        console.dir(line.toString());</span><br><span class="line">        next();</span><br><span class="line">    &#125;))</span><br><span class="line">;</span><br></pre></td></tr></table></figure></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2017/01/23/interview/" data-id="ck3ya0yi3000f0d8s4rymsh8s" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/interview/">interview</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-vue" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2017/01/19/vue/" class="article-date">
  <time datetime="2017-01-19T07:19:03.000Z" itemprop="datePublished">2017-01-19</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2017/01/19/vue/">vue</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="js"><a href="#js" class="headerlink" title="js"></a>js</h3><ol>
<li><p>js 链接 defer 和 async</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">defer 和 async 都是并行加载的，主要区别在于下载后何时执行。</span><br><span class="line">每一个 async 属性的脚本都在它下载结束之后立刻执行，所以就有可能出现脚本执行顺序被打乱的情况</span><br><span class="line">每一个 defer 属性的脚本会在 HTML 解析完成后, DOMContentLoaded 之前，按照 DOM 中的顺序执行（ie&gt;=10）</span><br><span class="line">defer 和 async 都只适用于外部脚本文件，对与内联的 script 标签是不起作用</span><br></pre></td></tr></table></figure>
</li>
<li><p>preload 用 “as” 或者用 “type” 属性来表示他们请求资源的优先级（比如说 preload 使用 as=”style” 属性将获得最高的优先级）。没有 “as” 属性的将被看作异步请求，“Early”意味着在所有未被预加载的图片请求之前被请求（“late”意味着之后）</p>
</li>
<li>WebRTC，名称源自网页即时通信（英语：Web Real-Time Communication）的缩写，是一个支持网页浏览器进行实时语音对话或视频对话的API。</li>
<li>Vue-intro  新功能引导  </li>
<li>Vm.$attrs  Vm.$attrs </li>
<li><home :title.sync="title"> //编译时会被扩展为 <home :title="title" @update:title="val => title = val"> // 子组件 // 所以子组件可以通过$emit 触发 update 方法改变 mounted(){ this.$emit(“update:title”, ‘这是新的title’) }</home></home></li>
<li>Vue.config.errorHandler   </li>
<li>v-pre  场景:vue 是响应式系统,但是有些静态的标签不需要多次编译,这样可以节省性能</li>
<li>v-loader transformAssetUrls<br>在模板编译过程中，编译器可以将某些特性转换为 require 调用，例如 src 中的 URL。因此这些目标资源可以被 webpack 处理。例如 <img src="./foo.png"> 会找到你文件系统中的 ./foo.png 并将其作为一个依赖包含在你的包里</li>
<li>view router加key  场景:由于 Vue 会复用相同组件, 即 /page/1 =&gt; /page/2 或者 /page?id=1 =&gt; /page?id=2 这类链接跳转时, 将不在执行created, mounted之类的钩子</li>
<li><p>生命周期</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">beforeCreate阶段：vue实例的挂载元素el和数据对象data都是undefined，还没有初始化。</span><br><span class="line">created阶段：vue实例的数据对象data有了，可以访问里面的数据和方法，未挂载到DOM，el还没有</span><br><span class="line">beforeMount阶段：vue实例的el和data都初始化了，但是挂载之前为虚拟的dom节点</span><br><span class="line">mounted阶段：vue实例挂载到真实DOM上，就可以通过DOM获取DOM节点</span><br><span class="line">beforeUpdate阶段：响应式数据更新时调用，发生在虚拟DOM打补丁之前，适合在更新之前访问现有的DOM，比如手动移除已添加的事件监听器</span><br><span class="line">updated阶段：虚拟DOM重新渲染和打补丁之后调用，组成新的DOM已经更新，避免在这个钩子函数中操作数据，防止死循环</span><br><span class="line">beforeDestroy阶段：实例销毁前调用，实例还可以用，this能获取到实例，常用于销毁定时器，解绑事件</span><br><span class="line">destroyed阶段：实例销毁后调用，调用后所有事件监听器会被移除，所有的子实例都会被销毁  </span><br><span class="line">```         </span><br><span class="line">1. __proto__ 属性，这是历史遗留的非标准的语法，但在现代浏览器中广泛实现。获得原型的更可靠方法是使用 Object.getPrototypeOf(new Object())；例如：</span><br><span class="line"> ```javascript</span><br><span class="line">const car = &#123;&#125;</span><br><span class="line">const list = []</span><br><span class="line"> </span><br><span class="line">console.log(Object.getPrototypeOf(car));</span><br><span class="line">console.log(Object.getPrototypeOf(list));</span><br></pre></td></tr></table></figure>
</li>
<li><p>Object.prototype.toString.call(variable) 用这个方法来判断变量类型目前是最可靠的了，它总能返回正确的值。</p>
<p>该方法返回 “[object type]”, 其中type是对象类型。</p>
</li>
<li>document.getElementsByClassName(‘test’);</li>
<li></li>
</ol>
<h3 id="内部机制"><a href="#内部机制" class="headerlink" title="内部机制"></a>内部机制</h3><p>vue-loader </p>
<p>compiler 目录包含 Vue.js 所有编译相关的代码。它包括把模板解析成 ast 语法树，ast 语法树优化，代码生成等功能。</p>
<p>微任务的例子：micortask</p>
<p>process.nextTick<br>promise<br>Object.observe</p>
<p>宏任务的例子：</p>
<p>setTimeout<br>setInterval<br>setImmediate<br>I/O</p>
<p>需要注意的是node 和 浏览器的 event loop 是有区别的(需要注意的是node v12.0 之后和浏览器处理事一致的)：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">浏览器的事件循环：</span><br><span class="line"></span><br><span class="line">执行全局Script同步代码，这些同步代码有一些是同步语句，有一些是异步语句（比如setTimeout等）；</span><br><span class="line">全局Script代码执行完毕后，调用栈Stack会清空；</span><br><span class="line">从微队列microtask queue中取出位于队首的回调任务，放入调用栈Stack中执行，执行完后microtask queue长度减1；</span><br><span class="line">继续取出位于队首的任务，放入调用栈Stack中执行，以此类推，直到直到把microtask queue中的所有任务都执行完毕。注意，如果在执行microtask的过程中，又产生了microtask，那么会加入到队列的末尾，也会在这个周期被调用执行；</span><br><span class="line">microtask queue中的所有任务都执行完毕，此时microtask queue为空队列，调用栈Stack也为空；</span><br><span class="line">取出宏队列macrotask queue中位于队首的任务，放入Stack中执行；</span><br><span class="line">执行完毕后，调用栈Stack为空；</span><br><span class="line">重复第3-7个步骤；</span><br><span class="line">重复第3-7个步骤；</span><br><span class="line">……</span><br><span class="line"></span><br><span class="line">NodeJS中微队列主要有2个：</span><br><span class="line">Next Tick Queue：是放置process.nextTick(callback)的回调任务的</span><br><span class="line">Other Micro Queue：放置其他microtask，比如Promise等</span><br><span class="line"></span><br><span class="line">具体参见： https://segmentfault.com/a/1190000016278115</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">timers 阶段：这个阶段执行timer（setTimeout、setInterval）的回调</span><br><span class="line">I/O callbacks 阶段：执行一些系统调用错误，比如网络通信的错误回调</span><br><span class="line">idle, prepare 阶段：仅node内部使用</span><br><span class="line">poll 阶段：获取新的I/O事件, 适当的条件下node将阻塞在这里</span><br><span class="line">check 阶段：执行 setImmediate() 的回调</span><br><span class="line">close callbacks 阶段：执行 socket 的 close 事件回调</span><br><span class="line"></span><br><span class="line">timers 是事件循环的第一个阶段，Node 会去检查有无已过期的timer，如果有则把它的回调压入timer的任务队列中等待执行，事实上，Node 并不能保证timer在预设时间到了就会立即执行，因为Node对timer的过期检查不一定靠谱，它会受机器上其它运行程序影响，或者那个时间点主线程不空闲。比如下面的代码，setTimeout() 和 setImmediate() 的执行顺序是不确定的。</span><br><span class="line"></span><br><span class="line">poll 阶段</span><br><span class="line">poll 阶段主要有2个功能：</span><br><span class="line"></span><br><span class="line">处理 poll 队列的事件</span><br><span class="line">当有已超时的 timer，执行它的回调函数</span><br><span class="line">even loop将同步执行poll队列里的回调，直到队列为空或执行的回调达到系统上限（上限具体多少未详），接下来even loop会去检查有无预设的setImmediate()，分两种情况：</span><br><span class="line"></span><br><span class="line">若有预设的setImmediate(), event loop将结束poll阶段进入check阶段，并执行check阶段的任务队列</span><br><span class="line">若没有预设的setImmediate()，event loop将阻塞在该阶段等待</span><br><span class="line">注意一个细节，没有setImmediate()会导致event loop阻塞在poll阶段，这样之前设置的timer岂不是执行不了了？所以咧，在poll阶段event loop会有一个检查机制，检查timer队列是否为空，如果timer队列非空，event loop就开始下一轮事件循环，即重新进入到timer阶段。</span><br><span class="line"></span><br><span class="line">check 阶段</span><br><span class="line">setImmediate()的回调会被加入check队列中，从event loop的阶段图可以知道，check阶段的执行顺序在poll阶段之后。</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">回顾上一篇，浏览器环境下，microtask的任务队列是每个macrotask执行完之后执行。而在Node.js中，microtask会在事件循环的各个阶段之间执行，也就是一个阶段执行完毕，就会去执行microtask队列的任务。详见：http://lynnelv.github.io/js-event-loop-nodejs</span><br><span class="line"></span><br><span class="line">process.nextTick() 会在各个事件阶段之间执行，一旦执行，要直到nextTick队列被清空，才会进入到下一个事件阶段，所以如果递归调用 process.nextTick()，会导致出现I/O starving（饥饿）的问题</span><br><span class="line"></span><br><span class="line">官方文档：https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/</span><br></pre></td></tr></table></figure>
<p>###vitual dom</p>
<p> Vue.js 实现响应式的核心是利用了 ES5 的 Object.defineProperty，这也是为什么 Vue.js 不能兼容 IE8 及以下浏览器的原因，我们先来对它有个直观的认识。值改变时会触发set方法。</p>
<p> 核心就是利用 Object.defineProperty 给数据添加了 getter 和 setter，目的就是为了在我们访问数据以及写数据的时候能自动执行一些逻辑：getter 做的事情是依赖收集，setter 做的事情是派发更新</p>
<p> 它会先执行 vm._render() 方法，因为之前分析过这个方法会生成 渲染 VNode，并且在这个过程中会对 vm 上的数据访问，这个时候就触发了数据对象的 getter。</p>
<p> 它并不会每次数据改变都触发 watcher 的回调，而是把这些 watcher 先添加到一个队列里，然后在 nextTick 后执行 flushSchedulerQueue。</p>
<p>VD 最大的特点是将页面的状态抽象为 JS 对象的形式，配合不同的渲染工具，使跨平台渲染成为可能。如 React 就借助 VD 实现了服务端渲染、浏览器渲染和移动端渲染等功能。<br>js计算-》生成渲染树-》渲染页面</p>
<p>通过VD的比较，我们可以将多个操作合并成一个批量的操作，从而减少dom重排的次数，进而缩短了生成渲染树和绘制所花的时间。</p>
<p>在mounted 方法中会将template 编译成为render 方法。这是一个编译过程，render中会调用createElement 创建vnode。</p>
<p><img src="https://ustbhuangyi.github.io/vue-analysis/assets/new-vue.png" alt="流程图片"></p>
<p>回到 mountComponent 函数的过程，我们已经知道 createElement 是如何创建了一个 VNode，接下来就是要把这个 VNode 渲染成一个真实的 DOM 并渲染出来，这个过程是通过 vm._update 完成的</p>
<p>Vue 的 _update 是实例的一个私有方法，它被调用的时机有 2 个，一个是首次渲染，一个是数据更新的时候；由于我们这一章节只分析首次渲染部分，数据更新部分会在之后分析响应式原理的时候涉及。_update 方法的作用是把 VNode 渲染成真实的 DOM</p>
<p>在我们之前对 setter 的分析过程知道，当响应式数据发送变化后，触发了 watcher.update()，只是把这个 watcher 推送到一个队列中，在 nextTick 后才会真正执行 watcher 的回调函数。而一旦我们设置了 sync，就可以在当前 Tick 中同步执行 watcher 的回调函数。</p>
<p>deep watcher 和 sync watcher  </p>
<h3 id="router-元数据"><a href="#router-元数据" class="headerlink" title="router 元数据"></a>router 元数据</h3><p> meta: { requiresAuth: true }  </p>
<h5 id="v-once-指令，你也能执行一次性地插值"><a href="#v-once-指令，你也能执行一次性地插值" class="headerlink" title="v-once 指令，你也能执行一次性地插值"></a>v-once 指令，你也能执行一次性地插值</h5><h4 id="v-slot-新的用法"><a href="#v-slot-新的用法" class="headerlink" title="v-slot 新的用法"></a>v-slot 新的用法</h4><p>v-slot 的别名是#。因此，可以用#header=”data” 来代替 v-slot:header=”data”。还可以使用 #header来代替 v-slot:header(前提:不是作用域插槽时)。对于默认插槽，在使用别名时需要指定默认名称。换句话说，需要这样写 #default=”data” 而不是#=”data”。</p>
<h5 id="Mustache-不能在-HTML-属性中使用，应使用-v-bind-指令："><a href="#Mustache-不能在-HTML-属性中使用，应使用-v-bind-指令：" class="headerlink" title="Mustache 不能在 HTML 属性中使用，应使用 v-bind 指令："></a>Mustache 不能在 HTML 属性中使用，应使用 v-bind 指令：</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;div v-bind:id=&quot;dynamicId&quot;&gt;&lt;/div&gt;</span><br></pre></td></tr></table></figure>
<h5 id="修饰符（Modifiers）是以半角句号-指明的特殊后缀，用于指出一个指定应该以特殊方式绑定。例如，-prevent-修饰符告诉-v-on-指令对于触发的事件调用-event-preventDefault"><a href="#修饰符（Modifiers）是以半角句号-指明的特殊后缀，用于指出一个指定应该以特殊方式绑定。例如，-prevent-修饰符告诉-v-on-指令对于触发的事件调用-event-preventDefault" class="headerlink" title="修饰符（Modifiers）是以半角句号 . 指明的特殊后缀，用于指出一个指定应该以特殊方式绑定。例如，.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()"></a>修饰符（Modifiers）是以半角句号 . 指明的特殊后缀，用于指出一个指定应该以特殊方式绑定。例如，.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 阻止单击事件冒泡 --&gt;</span><br><span class="line">&lt;a v-on:click.stop=&quot;doThis&quot;&gt;&lt;/a&gt;</span><br><span class="line">&lt;!-- 提交事件不再重载页面 --&gt;</span><br><span class="line">&lt;form v-on:submit.prevent=&quot;onSubmit&quot;&gt;&lt;/form&gt;</span><br><span class="line">&lt;!-- 修饰符可以串联  --&gt;</span><br><span class="line">&lt;a v-on:click.stop.prevent=&quot;doThat&quot;&gt;&lt;/a&gt;</span><br><span class="line">&lt;!-- 只有修饰符 --&gt;</span><br><span class="line">&lt;form v-on:submit.prevent&gt;&lt;/form&gt;</span><br><span class="line">&lt;!-- 添加事件侦听器时使用事件捕获模式 --&gt;</span><br><span class="line">&lt;div v-on:click.capture=&quot;doThis&quot;&gt;...&lt;/div&gt;</span><br><span class="line">&lt;!-- 只当事件在该元素本身（而不是子元素）触发时触发回调 --&gt;</span><br><span class="line">&lt;div v-on:click.self=&quot;doThat&quot;&gt;...&lt;/div&gt;</span><br><span class="line">&lt;a v-on:click.once=&quot;doThis&quot;&gt;&lt;/a&gt;</span><br></pre></td></tr></table></figure>
<h5 id="过滤器函数总接受表达式的值作为第一个参数。"><a href="#过滤器函数总接受表达式的值作为第一个参数。" class="headerlink" title="过滤器函数总接受表达式的值作为第一个参数。"></a>过滤器函数总接受表达式的值作为第一个参数。</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">new Vue(&#123;</span><br><span class="line">  // ...</span><br><span class="line">  filters: &#123;</span><br><span class="line">    capitalize: function (value) &#123;</span><br><span class="line">      if (!value) return &apos;&apos;</span><br><span class="line">      value = value.toString()</span><br><span class="line">      return value.charAt(0).toUpperCase() + value.slice(1)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line">过滤器可以串联：</span><br><span class="line">&#123;&#123; message | filterA | filterB &#125;&#125;</span><br></pre></td></tr></table></figure>
<h5 id="v-bind-缩写"><a href="#v-bind-缩写" class="headerlink" title="v-bind 缩写"></a>v-bind 缩写</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 完整语法 --&gt;</span><br><span class="line">&lt;a v-bind:href=&quot;url&quot;&gt;&lt;/a&gt;</span><br><span class="line">&lt;!-- 缩写 --&gt;</span><br><span class="line">&lt;a :href=&quot;url&quot;&gt;&lt;/a&gt;</span><br><span class="line">v-on 缩写</span><br><span class="line"></span><br><span class="line">&lt;!-- 完整语法 --&gt;</span><br><span class="line">&lt;a v-on:click=&quot;doSomething&quot;&gt;&lt;/a&gt;</span><br><span class="line">&lt;!-- 缩写 --&gt;</span><br><span class="line">&lt;a @click=&quot;doSomething&quot;&gt;&lt;/a&gt;</span><br></pre></td></tr></table></figure>
<h5 id="按键修饰符"><a href="#按键修饰符" class="headerlink" title="按键修饰符"></a>按键修饰符</h5><p>记住所有的 keyCode 比较困难，所以 Vue 为最常用的按键提供了别名：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&lt;!-- 同上 --&gt;</span><br><span class="line">&lt;input v-on:keyup.enter=&quot;submit&quot;&gt;</span><br><span class="line">&lt;!-- 缩写语法 --&gt;</span><br><span class="line">&lt;input @keyup.enter=&quot;submit&quot;&gt;</span><br><span class="line">全部的按键别名：</span><br><span class="line">.enter</span><br><span class="line">.tab</span><br><span class="line">.delete (捕获 “删除” 和 “退格” 键)</span><br><span class="line">.esc</span><br><span class="line">.space</span><br><span class="line">.up</span><br><span class="line">.down</span><br><span class="line">.left</span><br><span class="line">.right</span><br></pre></td></tr></table></figure>
<h5 id="绑定属性值"><a href="#绑定属性值" class="headerlink" title="绑定属性值"></a>绑定属性值</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;input</span><br><span class="line">  type=&quot;checkbox&quot;</span><br><span class="line">  v-model=&quot;toggle&quot;</span><br><span class="line">  v-bind:true-value=&quot;a&quot;</span><br><span class="line">  v-bind:false-value=&quot;b&quot;</span><br><span class="line">&gt;</span><br></pre></td></tr></table></figure>
<h5 id="修饰符"><a href="#修饰符" class="headerlink" title="修饰符"></a>修饰符</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">在默认情况下， v-model 在 input 事件中同步输入框的值与数据 (除了 上述 IME 部分)，但你可以添加一个修饰符 lazy ，从而转变为在 change 事件中同步：</span><br><span class="line">&lt;!-- 在 &quot;change&quot; 而不是 &quot;input&quot; 事件中更新 --&gt;</span><br><span class="line">&lt;input v-model.lazy=&quot;msg&quot; &gt;</span><br><span class="line">.number</span><br><span class="line"></span><br><span class="line">如果想自动将用户的输入值转为 Number 类型（如果原值的转换结果为 NaN 则返回原值），可以添加一个修饰符 number 给 v-model 来处理输入值：</span><br><span class="line">&lt;input v-model.number=&quot;age&quot; type=&quot;number&quot;&gt;</span><br><span class="line">这通常很有用，因为在 type=&quot;number&quot; 时 HTML 中输入的值也总是会返回字符串类型。</span><br><span class="line">.trim</span><br><span class="line"></span><br><span class="line">如果要自动过滤用户输入的首尾空格，可以添加 trim 修饰符到 v-model 上过滤输入：</span><br><span class="line">&lt;input v-model.trim=&quot;msg&quot;&gt;</span><br></pre></td></tr></table></figure>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2017/01/19/vue/" data-id="ck3ya0yiv00180d8s83emf5ns" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/vue-eventloop-js/">vue eventloop js</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-webpack" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2017/01/17/webpack/" class="article-date">
  <time datetime="2017-01-17T06:58:02.000Z" itemprop="datePublished">2017-01-17</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2017/01/17/webpack/">webpack</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="babel相关"><a href="#babel相关" class="headerlink" title="babel相关"></a>babel相关</h3><ol>
<li><p>虽然@babel/polyfill提供了我们想要的所有新方法新类，但是这里依然存在一些问题：</p>
<p>体积太大：比如我只用了String的新特性，但是我把整个包都引进来了，，这不是徒增了很多无用的代码。<br>污染全局环境：如果你引用了 @babel/polyfill，那么像Promise这样的新类就是挂载在全局上的，这样就会污染了全局命名空间。可能在一个团建建立的项目问题不太大，但是如果你是一个工具的开发者，你把全局环境污染了，别人用你的工具，就有可能把别人给坑了</p>
</li>
<li><p>@babel/plugin-transform-runtime会为代码创建一个沙盒环境，为core-js这里内建的实例提供假名，你可以无缝的使用这些新特性，而不需要使用require polyfill。</p>
<p>一个解决方案就是引入transform runtime 来替代 @babel/polyfill。<br>幸运的是，我们有env这个preset，它又一个useBuiltIns选项，如果设置成”usage”，那么将会自动检测语法帮你require你代码中使用到的功能。  </p>
</li>
<li><p>@babel/core<br>其中最核心的包就是@babel/core，它主要的作用就是编译.</p>
<p>Babel-cli<br>光有core是无法在命令行使用这些功能的，@babel/cli支持你直接在命令行中编译代码。<br>这句话会编译你src目录下的所有js代码，并编译成你想要的那样（babel.config.js配置的），并输出到lib目录下。 </p>
</li>
<li>@babel/preset-env<br>如果useBuiltIns为true，项目中必须引入babel-polyfill。</li>
</ol>
<ol>
<li>Vue Loader 是一个 webpack 的 loader，它允许你以一种名为单文件组件 (SFCs)的格式撰写 Vue 组件.   </li>
<li><p>autoprefixer 自动补充前缀</p>
</li>
<li><p>Hot Module Replacement（以下简称 HMR）是 webpack 发展至今引入的最令人兴奋的特性之一 ，当你对代码进行修改并保存后，webpack 将对代码重新打包，并将新的模块发送到浏览器端，浏览器通过新的模块替换老的模块，这样在不刷新浏览器的前提下就能够对应用进行更新。</p>
</li>
<li>webpack-dev-server 修改了webpack 配置中的 entry 属性，在里面添加了 webpack-dev-client 的代码，这样在最后的 bundle.js 文件中就会有接收 websocket 消息的代码了。</li>
<li></li>
<li><p>WebPack可以看做是模块打包机：它做的事情是，分析你的项目结构，找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言（Scss，TypeScript等），并将其打包为合适的格式以供浏览器使用。</p>
</li>
<li><p>Webpack splitchunk 将各个模块的交集部分抽离出来 </p>
</li>
<li><p>Webpack ProvidePlugin 自动加载js，不必import。<br>new webpack.ProvidePlugin({<br>  _map: [‘lodash’, ‘map’]<br>})</p>
</li>
<li><p>Webpack在打包时可以为我们生成的source maps，这为我们提供了一种对应编译文件和源文件的方法，使得编译后的代码可读性更高，也更容易调试</p>
</li>
</ol>
<p>具体配置参考：<a href="http://www.jianshu.com/p/42e11515c10f" target="_blank" rel="noopener">http://www.jianshu.com/p/42e11515c10f</a></p>
<p>感叹号的作用在于使同一文件能够使用不同类型的loader</p>
<p>对css 分模块：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">        test: /\.css$/,</span><br><span class="line">        loader: &apos;style!css?modules&apos;//跟前面相比就在后面加上了?modules</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>Loaders和Plugins常常被弄混，但是他们其实是完全不同的东西，可以这么来说，loaders是在打包构建过程中用来处理源文件的（JSX，Scss，Less..），一次处理一个，插件并不直接操作单个文件，它直接对整个构建过程其作用。</p>
<h4 id="常用命令"><a href="#常用命令" class="headerlink" title="常用命令"></a>常用命令</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ webpack --config webpack.min.js //另一份配置文件</span><br><span class="line"></span><br><span class="line">$ webpack --display-error-details //显示异常信息</span><br><span class="line"></span><br><span class="line">$ webpack --watch   //监听变动并自动打包</span><br><span class="line"> </span><br><span class="line">$ webpack -p    //压缩混淆脚本，这个非常非常重要！</span><br><span class="line"> </span><br><span class="line">$ webpack -d    //生成map映射文件，告知哪些模块被最终打包到哪里了</span><br></pre></td></tr></table></figure>
<p>对公共库的封装：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">entry: &#123;</span><br><span class="line">  vendor: [&quot;jquery&quot;, &quot;other-lib&quot;],</span><br><span class="line">  app: &quot;./entry&quot;</span><br><span class="line">&#125;</span><br><span class="line">new CommonsChunkPlugin(&#123;</span><br><span class="line">  name: &quot;vendor&quot;,</span><br><span class="line"></span><br><span class="line">  // filename: &quot;vendor.js&quot;</span><br><span class="line">  // (Give the chunk a different name)</span><br><span class="line"></span><br><span class="line">  minChunks: Infinity,</span><br><span class="line">  // (with more entries, this ensures that no other module</span><br><span class="line">  //  goes into the vendor chunk)</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<p>关于express webpack middleware 的配置</p>
<p><a href="http://www.cnblogs.com/linfangshuhellowored/p/5657285.html" target="_blank" rel="noopener">http://www.cnblogs.com/linfangshuhellowored/p/5657285.html</a></p>
<p>给文件自动添加hash后缀</p>
<p>根据chunkhash的定义知道，chunkhash是根据具体模块文件的内容计算所得的hash值，所以某个文件的改动只会影响它本身的hash指纹，不会影响其他文件。配置webpack的output如下：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">output: &#123;</span><br><span class="line">    filename: &apos;[name].[chunkhash:8].js&apos;,</span><br><span class="line">    path: __dirname + &apos;/built&apos;</span><br><span class="line">&#125;</span><br><span class="line">output: &#123;</span><br><span class="line">    filename: &apos;[name].[hash:8].js&apos;,</span><br><span class="line">    path: __dirname + &apos;/built&apos;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2017/01/17/webpack/" data-id="ck3ya0yiw001a0d8s6hmaag06" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/webpack/">webpack</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-loadtest" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2017/01/17/loadtest/" class="article-date">
  <time datetime="2017-01-17T01:41:01.000Z" itemprop="datePublished">2017-01-17</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2017/01/17/loadtest/">loadtest</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="loadtest-压力测试"><a href="#loadtest-压力测试" class="headerlink" title="loadtest 压力测试"></a>loadtest 压力测试</h3><p>可用powershell 或linux bash </p>
<p>命令行如果加post body 会报错</p>
<p>常用参数：</p>
<p>-T 表示持续时间</p>
<p>-c 并行数量</p>
<p>-n 总的请求</p>
<p>-m  get,put,post</p>
<p>–rps 每秒发送请求数</p>
<p>-P Request body 数据</p>
<p>-p body 数据存在的文件路径</p>
<p>-H header 添加</p>
<p>-C 设置cookie<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">param(</span><br><span class="line">    [int] $iterations = 6000,</span><br><span class="line">    [int] $rps = 500,</span><br><span class="line">    [string][ValidateSet(&quot;plaintext&quot;)] $variation = &quot;plaintext&quot;)</span><br><span class="line"></span><br><span class="line">if ($variation -eq &quot;plaintext&quot;)</span><br><span class="line">&#123;</span><br><span class="line">    $url = &quot;http://wh.etao.cn/auth/test&quot;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Write-Host -ForegroundColor Green Beginning workload</span><br><span class="line">Write-Host &quot;`&amp; loadtest -k -n $iterations -c 100 --rps $rps $url&quot;</span><br><span class="line">Write-Host</span><br><span class="line"></span><br><span class="line">&amp; loadtest -k -n $iterations -c 100 --rps $rps $url</span><br></pre></td></tr></table></figure></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">loadtest -c 5 -t 2 -m post -T &apos;application/json&apos;  -P &apos;&#123;&quot;message&quot;:&quot;hello&quot;&#125;&apos;  -H &quot;Accept: application/json; q=0.9, application/xml; q=0.6&quot; http://cttest.etao.cn:8011/api/auth/test</span><br></pre></td></tr></table></figure>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2017/01/17/loadtest/" data-id="ck3ya0yim000x0d8skh91lev6" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/loadtest/">loadtest</a></li></ul>

    </footer>
  </div>
  
</article>


  
    <article id="post-pm2" class="article article-type-post" itemscope="" itemprop="blogPost">
  <div class="article-meta">
    <a href="/2016/12/29/pm2/" class="article-date">
  <time datetime="2016-12-29T09:53:39.000Z" itemprop="datePublished">2016-12-29</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 itemprop="name">
      <a class="article-title" href="/2016/12/29/pm2/">pm2</a>
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h3 id="pm2-start-启动文件的设置"><a href="#pm2-start-启动文件的设置" class="headerlink" title="pm2 start 启动文件的设置"></a>pm2 start 启动文件的设置</h3><ol>
<li>通过 pm2 ecosystem 生成文件</li>
<li><p>在配置文件中配置，主要参数如下：
　　</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">min_uptime：最小运行时间，这里设置的是60s即如果应用程序在60s内退出，pm2会认为程序异常退出，此时触发重启max_restarts设置数量</span><br><span class="line"></span><br><span class="line">exec_mode：应用程序启动模式，这里设置的是cluster_mode（集群），默认是fork</span><br><span class="line">error_file：自定义应用程序的错误日志文件</span><br><span class="line">out_file：自定义应用程序日志文件</span><br><span class="line">pid_file：自定义应用程序的pid文件</span><br><span class="line">watch：是否启用监控模式，默认是false。如果设置成true，当应用程序变动时，pm2会自动重载。这里也可以设置你要监控的文件</span><br><span class="line"></span><br><span class="line">exec_interpreter：应用程序的脚本类型，这里使用的shell，默认是nodejs</span><br><span class="line">defaults to “node”. can be “python”, “ruby”, “bash” or whatever interpreter you wish to use. “none” will execute your app as a binary executable</span><br><span class="line"></span><br><span class="line">当使用babel的时候： exec_interpreter:&quot;babel-node&quot;</span><br><span class="line"> </span><br><span class="line">max_memory_restart  超出这个内存后会重新启动</span><br></pre></td></tr></table></figure>
</li>
<li><p>可以设置watch 的目录</p>
</li>
</ol>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  &quot;name&quot;        : &quot;fis-receiver&quot;,  // 应用名称</span><br><span class="line">  &quot;script&quot;      : &quot;./bin/www&quot;,  // 实际启动脚本</span><br><span class="line">  &quot;cwd&quot;         : &quot;./&quot;,  // 当前工作路径</span><br><span class="line">  &quot;watch&quot;: [  // 监控变化的目录，一旦变化，自动重启</span><br><span class="line">    &quot;bin&quot;,</span><br><span class="line">    &quot;routers&quot;</span><br><span class="line">  ],</span><br><span class="line">  &quot;ignore_watch&quot; : [  // 从监控目录中排除</span><br><span class="line">    &quot;node_modules&quot;, </span><br><span class="line">    &quot;logs&quot;,</span><br><span class="line">    &quot;public&quot;</span><br><span class="line">  ],</span><br><span class="line">  &quot;watch_options&quot;: &#123;</span><br><span class="line">    &quot;followSymlinks&quot;: false</span><br><span class="line">  &#125;,</span><br><span class="line">  &quot;error_file&quot; : &quot;./logs/app-err.log&quot;,  // 错误日志路径</span><br><span class="line">  &quot;out_file&quot;   : &quot;./logs/app-out.log&quot;,  // 普通日志路径</span><br><span class="line">  &quot;env&quot;: &#123;</span><br><span class="line">      &quot;NODE_ENV&quot;: &quot;production&quot;  // 环境参数，当前指定为生产环境</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2016/12/29/pm2/" data-id="ck3ya0yid000p0d8s9uxpgdh7" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/pm2/">pm2</a></li></ul>

    </footer>
  </div>
  
</article>


  


  <nav id="page-nav">
    <a class="extend prev" rel="prev" href="/">&laquo; __('prev')</a><a class="page-number" href="/">1</a><span class="page-number current">2</span><a class="page-number" href="/page/3/">3</a><a class="extend next" rel="next" href="/page/3/">__('next') &raquo;</a>
  </nav>
</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/css/">css</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/docker/">docker</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/es/">es</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/eslint/">eslint</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/git/">git</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/hexo/">hexo</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/http/">http</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/https/">https</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/interview/">interview</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/loadtest/">loadtest</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/ops/">ops</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/pattern/">pattern</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/pm2/">pm2</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/postgre/">postgre</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/regex/">regex</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/ts/">ts</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/useful-package/">useful package</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/vue-eventloop-js/">vue eventloop js</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/web-安全/">web 安全</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/webpack/">webpack</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/安全/">安全</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/零碎/">零碎</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/css/" style="font-size: 10px;">css</a> <a href="/tags/docker/" style="font-size: 10px;">docker</a> <a href="/tags/es/" style="font-size: 20px;">es</a> <a href="/tags/eslint/" style="font-size: 10px;">eslint</a> <a href="/tags/git/" style="font-size: 10px;">git</a> <a href="/tags/hexo/" style="font-size: 10px;">hexo</a> <a href="/tags/http/" style="font-size: 10px;">http</a> <a href="/tags/https/" style="font-size: 10px;">https</a> <a href="/tags/interview/" style="font-size: 10px;">interview</a> <a href="/tags/loadtest/" style="font-size: 10px;">loadtest</a> <a href="/tags/ops/" style="font-size: 10px;">ops</a> <a href="/tags/pattern/" style="font-size: 10px;">pattern</a> <a href="/tags/pm2/" style="font-size: 10px;">pm2</a> <a href="/tags/postgre/" style="font-size: 10px;">postgre</a> <a href="/tags/regex/" style="font-size: 10px;">regex</a> <a href="/tags/ts/" style="font-size: 10px;">ts</a> <a href="/tags/useful-package/" style="font-size: 10px;">useful package</a> <a href="/tags/vue-eventloop-js/" style="font-size: 10px;">vue eventloop js</a> <a href="/tags/web-安全/" style="font-size: 10px;">web 安全</a> <a href="/tags/webpack/" style="font-size: 10px;">webpack</a> <a href="/tags/安全/" style="font-size: 10px;">安全</a> <a href="/tags/零碎/" style="font-size: 10px;">零碎</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/12/">December 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/11/">November 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/08/">August 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/07/">July 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/06/">June 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/05/">May 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/04/">April 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/02/">February 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/02/">February 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/01/">January 2017</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2016/12/">December 2016</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2019/12/09/security-1/">security</a>
          </li>
        
          <li>
            <a href="/2019/11/08/encoding/">encoding</a>
          </li>
        
          <li>
            <a href="/2019/08/23/graphql/">graphql</a>
          </li>
        
          <li>
            <a href="/2019/07/02/linux/">linux</a>
          </li>
        
          <li>
            <a href="/2019/07/02/es8/">es8</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2019 ryansecreat<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>

  </div>
</body>
</html>